<?php
/**
 * Created by PhpStorm.
 * User: longli
 * VX: isa1589518286
 * Date: 2020/12/02
 * Time: 14:31
 * @link http://www.lmterp.cn
 */
namespace app\common\model;

use app\common\library\Tools;

class Purchase extends BaseModel
{
    protected $pk = 'purchase_id';

    protected $autoWriteTimestamp = 'datetime';

    // 设置 json 字段
    protected $json = ['ext_json'];

    protected $insert = ['create_by', 'update_by'];

    protected $update = ['update_by'];

    protected function getPayStatusAttr($value)
    {
        return isset(FinancePayment::$PAY_STATUS[$value]) ? FinancePayment::$PAY_STATUS[$value] : $value;
    }

    /**
     * 待处理
     * @var int
     */
    const ORDER_STATUS_WAIT = 0;

    /**
     * 采购建议
     * @var int
     */
    const ORDER_STATUS_SUG = 10;

    /**
     * 已取消
     * @var int
     */
    const ORDER_STATUS_CANCEL = 20;

    /**
     * 采购中
     * @var int
     */
    const ORDER_STATUS_GENERATE = 30;

    /**
     * 供应商出库
     * @var int
     */
    const ORDER_STATUS_OUT = 40;

    /**
     * 运输中
     * @var int
     */
    const ORDER_STATUS_SHIPPING = 50;

    /**
     * 采购到货
     * @var int
     */
    const ORDER_STATUS_RECV = 60;

    /**
     * 质检中
     * @var int
     */
    const ORDER_STATUS_CHE_INFO = 70;

    /**
     * 采购异常
     * @var int
     */
    const ORDER_STATUS_EXCEPTION = 80;

    /**
     * 退货
     * @var int
     */
    const ORDER_STATUS_RET = 90;

    /**
     * 换货
     * @var int
     */
    const ORDER_STATUS_EX = 100;

    /**
     * 补发
     * @var int
     */
    const ORDER_STATUS_REISSUE = 110;

    /**
     * 入库中
     * @var int
     */
    const ORDER_STATUS_IN = 120;

    /**
     * 入库异常
     * @var int
     */
    const ORDER_STATUS_IN_EX = 130;

    /**
     * 待上架
     * @var int
     */
    const ORDER_STATUS_WAIT_UP = 140;

    /**
     * 部分入库
     * @var int
     */
    const ORDER_STATUS_IN_PART = 150;

    /**
     * 全部入库
     * @var int
     */
    const ORDER_STATUS_IN_SUCC = 160;

    /**
     * 核销中
     * @var int
     */
    const ORDER_STATUS_FCHE_ING = 170;

    /**
     * 核销异常
     * @var int
     */
    const ORDER_STATUS_CHE_EX = 180;

    /**
     * 核销完成
     * @var int
     */
    const ORDER_STATUS_CHE_OK = 190;

    public static $ORDER_STATUS = [
        self::ORDER_STATUS_WAIT => '待处理',
        self::ORDER_STATUS_SUG => '采购建议',
        self::ORDER_STATUS_CANCEL => '已取消',
        self::ORDER_STATUS_GENERATE => '采购中',
        self::ORDER_STATUS_OUT => '供应商出库',
        self::ORDER_STATUS_SHIPPING => '运输中',
        self::ORDER_STATUS_RECV => '采购到货',
        self::ORDER_STATUS_CHE_INFO => '质检中',
        self::ORDER_STATUS_EXCEPTION => '采购异常',
        self::ORDER_STATUS_RET => '退货',
        self::ORDER_STATUS_EX => '换货',
        self::ORDER_STATUS_REISSUE => '补发',
        self::ORDER_STATUS_IN => '入库中',
        self::ORDER_STATUS_IN_EX => '入库异常',
        self::ORDER_STATUS_WAIT_UP => '待上架',
        self::ORDER_STATUS_IN_PART => '部分入库',
        self::ORDER_STATUS_IN_SUCC => '全部入库',
        self::ORDER_STATUS_FCHE_ING => '核销中',
        self::ORDER_STATUS_CHE_EX => '核销异常',
        self::ORDER_STATUS_CHE_OK => '核销完成',
    ];

    protected function getOrderStatusAttr($value)
    {
        return isset(self::$ORDER_STATUS[$value]) ? self::$ORDER_STATUS[$value] : $value;
    }

    protected function getPayTypeAttr($value)
    {
        return isset(FinancePayment::$PAY_TYPE[$value]) ? FinancePayment::$PAY_TYPE[$value] : $value;
    }

    /**
     * 付款金额
     * @return \think\model\relation\HasMany
     * @date 2020/11/14
     * @author longli
     */
    public function payment()
    {
        return $this->hasMany(FinancePayment::class, 'ref_sn', 'purchase_sn')->where("ref_id_type", static::getTable());
    }

    /**
     * 关联仓库
     * @return \think\model\relation\BelongsTo
     * @date 2020/11/07
     * @author longli
     */
    public function warehouse()
    {
        return $this->belongsTo(Warehouse::class);
    }

    /**
     * 关联供应商
     * @return \think\model\relation\BelongsTo
     * @date 2020/11/07
     * @author longli
     */
    public function producer()
    {
        return $this->belongsTo(Producer::class);
    }

    /**
     * 采购人
     * @return \think\model\relation\BelongsTo
     * @date 2020/11/14
     * @author longli
     */
    public function buyer()
    {
        return $this->belongsTo(Admin::class, 'buyer_user_id', 'id');
    }

    /**
     * 收货人
     * @return \think\model\relation\BelongsTo
     * @date 2021/01/22
     * @author longli
     */
    public function recv()
    {
        return $this->belongsTo(Admin::class, 'recv_user_id', 'id');
    }

    /**
     * 关联采购商品详情
     * @return \think\model\relation\HasMany
     * @date 2020/11/07
     * @author longli
     */
    public function info()
    {
        return $this->hasMany(PurchaseInfo::class)->order("sku");
    }

    /**
     * 关联物流表
     * @return \think\model\relation\HasMany
     * @date 2020/11/07
     * @author longli
     */
    public function track()
    {
        return $this->hasMany(PurchaseTrack::class);
    }

    /**
     * 关联采购退货
     * @return \think\model\relation\HasMany
     * @date 2020/12/29
     * @author longli
     */
    public function pren()
    {
        return $this->hasMany(PurchaseReturn::class);
    }

    /**
     * 关联采购退货信息
     * @return \think\model\relation\HasMany
     * @date 2020/12/29
     * @author longli
     */
    public function prenInfo()
    {
        return $this->hasMany(PurchaseTerpInfo::class,'purchase_id', 'purchase_id')
            ->where("id_type", PurchaseReturn::getTable());
    }

    /**
     * 关联采购异常
     * @return \think\model\relation\HasMany
     * @date 2020/12/29
     * @author longli
     */
    public function pexce()
    {
        return $this->hasMany(PurchaseException::class);
    }

    /**
     * 关联采购换货信息
     * @return \think\model\relation\HasMany
     * @date 2020/12/29
     * @author longli
     */
    public function pexchangeInfo()
    {
        return $this->hasMany(PurchaseTerpInfo::class,'purchase_id', 'purchase_id')
            ->where("id_type", PurchaseExchange::getTable());
    }

    /**
     * 关联采购异常信息
     * @return \think\model\relation\HasMany
     * @date 2020/12/29
     * @author longli
     */
    public function pexceInfo()
    {
        return $this->hasMany(PurchaseTerpInfo::class,'purchase_id', 'purchase_id')
            ->where("id_type", PurchaseException::getTable());
    }

    /**
     * 关联采购异常
     * @return \think\model\relation\HasMany
     * @date 2020/12/29
     * @author longli
     */
    public function exception()
    {
        return $this->hasMany(PurchaseException::class);
    }

    /**
     * 采购单是否存在
     * @param string|int $po 采购单号或者采购id
     * @return bool
     * @date 2020/11/07
     * @author longli
     */
    public static function hasPurchase($po)
    {
        return !!static::where("purchase_id", $po)
            ->whereOr("purchase_sn", $po)
            ->count();
    }

    /**
     * 检查采购单的 SKU 是否存在
     * @param string|string[] 商品 SKU
     * @return bool
     * @date 2020/12/23
     * @author longli
     */
    public function hasSku($sku)
    {
        if(!is_array($sku)) $sku = explode(',', $sku);
        $infoSku = $this->getSkus();
        return \app\common\library\Tools::containArray($infoSku, $sku, false);
    }

    /**
     * 获取当前采购单下的所有 SKU
     * @return array
     * @date 2020/12/23
     * @author longli
     */
    public function getSkus()
    {
        if($this->info->isEmpty()) return [];
        return array_column($this->info->toArray(), 'sku');
    }

    /**
     * 检查 sku 是否属于当前采购单
     * @param string|string[] $skus 商品 sku
     * @return array|bool 返回数组不是属于当前采购单的 sku, true 则全部属于当前采购单
     * @date 2021/01/01
     * @author longli
     */
    public function isHasSku($skus = [])
    {
        if(is_string($skus)) $skus = explode(',', $skus);
        $purSkus = $this->getSkus();
        $diff = array_diff($skus, $purSkus);
        return count($diff) > 0 ? $diff : true;
    }

    /**
     * 通过采购ID 或者采购单号获取一条数据
     * @param string $po 采购单号
     * @return Purchase
     * @date 2020/12/23
     * @author longli
     */
    public static function getBySn($po)
    {
        return static::where("purchase_id", $po)
            ->whereOr("purchase_sn", $po)
            ->find();
    }

    /**
     * 检查采购单是否已全部入库
     * @return bool
     * @date 2020/12/25
     * @author longli
     */
    public function isInStoreAll()
    {
        $ret = true;
        foreach($this->info as $info)
        {
            if(!$info->getNotStoreQty())
            {
               $info->store_status = PurchaseInfo::STORE_SUCC;
               $info->save();
            }
            else
            {
                $ret = false;
            }
        }
        return $ret;
    }

    /**
     * 检查采购单是否已全部到货
     * @return bool
     * @date 2020/12/25
     * @author longli
     */
    public function isRecvAll()
    {
        foreach($this->info as $info)
        {
            if($info->getNotStoreQty()) return false;
        }
        return true;
    }

    /**
     * 更新采购单到货状态
     * @return bool 收货成功返回 true, 失败返回 false
     * @date 2020/12/28
     * @author longli
     */
    public function recvPur()
    {
        if($this->getData('order_status') < self::ORDER_STATUS_RECV)
        {
            $this->order_status = self::ORDER_STATUS_RECV;
            $this->recv_date = Tools::now();
            $user = session("fanxi");
            if(!empty($user)) $this->recv_user_id = $user->id;
            $this->save();
        }
        return true;
    }

    /**
     * 获取下过单采购员
     * @return array
     * @date 2021/01/23
     * @author longli
     */
    public static function getBuyers()
    {
        $buyer = static::field("DISTINCT buyer_user_id")->select()->toArray();
        if(empty($buyer)) return [];
        $in = array_column($buyer, 'buyer_user_id');
        return Admin::field(["id", "nickname"])
            ->whereIn("id", $in)
            ->select()
            ->toArray();
    }
}
